home *** CD-ROM | disk | FTP | other *** search
-
- /*
- * (a) (C) 1990 by Adobe Systems Incorporated. All rights reserved.
- *
- * (b) If this Sample Code is distributed as part of the Display PostScript
- * System Software Development Kit from Adobe Systems Incorporated,
- * then this copy is designated as Development Software and its use is
- * subject to the terms of the License Agreement attached to such Kit.
- *
- * (c) If this Sample Code is distributed independently, then the following
- * terms apply:
- *
- * (d) This file may be freely copied and redistributed as long as:
- * 1) Parts (a), (d), (e) and (f) continue to be included in the file,
- * 2) If the file has been modified in any way, a notice of such
- * modification is conspicuously indicated.
- *
- * (e) PostScript, Display PostScript, and Adobe are registered trademarks of
- * Adobe Systems Incorporated.
- *
- * (f) THE INFORMATION BELOW IS FURNISHED AS IS, IS SUBJECT TO
- * CHANGE WITHOUT NOTICE, AND SHOULD NOT BE CONSTRUED
- * AS A COMMITMENT BY ADOBE SYSTEMS INCORPORATED.
- * ADOBE SYSTEMS INCORPORATED ASSUMES NO RESPONSIBILITY
- * OR LIABILITY FOR ANY ERRORS OR INACCURACIES, MAKES NO
- * WARRANTY OF ANY KIND (EXPRESS, IMPLIED OR STATUTORY)
- * WITH RESPECT TO THIS INFORMATION, AND EXPRESSLY
- * DISCLAIMS ANY AND ALL WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR PARTICULAR PURPOSES AND NONINFRINGEMENT
- * OF THIRD PARTY RIGHTS.
- */
-
- /*
- * DrawingView.m
- *
- * This view represents the page that the image is drawn onto. It is
- * a subview of the DocView. The DocView is the document view of
- * the ClipView. This view's real size grows with the scale but the
- * bounds always stays the same.
- *
- *
- * Version: 2.0
- * Author: Ken Fromm
- * History:
- * 03-07-91 Added this comment.
- */
-
- #import "DrawingView.h"
- #import "DrawingViewWraps.h"
- #import "DocView.h"
- #import "Graphic.h"
- #import "ScrollApp.h"
- #import <objc/List.h>
- #import <appkit/Button.h>
- #import <appkit/Control.h>
- #import <appkit/Matrix.h>
- #import <appkit/nextstd.h>
- #import <dpsclient/dpsclient.h>
- #import <dpsclient/wraps.h>
-
- extern void initGparms();
- extern void setGparms();
-
- @implementation DrawingView
-
- /*
- * Allocate a gstate, set the clipping to NO because it will be clipped
- * by the clip view.
- */
- +newFrame:(NXRect *) frm
- {
- self = [super newFrame:frm];
-
- drawUpath = [NXApp getUpathBuffer];
- drawManner = UPATH;
-
- return self;
- }
-
- - free
- {
- [self freeGraphics];
-
- return [super free];
- }
-
- - setFieldsMode:(BOOL) mode
- {
- displayFields = eraseFields = mode;
-
- return self;
- }
-
- - setTypeOfDrawing:sender
- {
- id matrixId;
-
- drawFrame = ([sender selectedRow] == 1);
-
- matrixId = [NXApp getStrokingMatrix];
- [[matrixId cellAt:0 :0] setEnabled:drawFrame];
- [[matrixId cellAt:1 :0] setEnabled:drawFrame];
-
- matrixId = [NXApp getParameterMatrix];
- [[matrixId cellAt:0 :0] setEnabled:!drawFrame];
- [[matrixId cellAt:1 :0] setEnabled:!drawFrame];
-
- [NXApp redrawAction:self];
-
- return self;
- }
-
- - setSelectivity:sender
- {
- drawEverything = ([sender selectedRow] == 1);
-
- [NXApp redrawAction:self];
-
- return self;
- }
-
- - setDrawingManner:sender
- {
- drawManner = [sender selectedRow];
-
- [NXApp redrawAction:self];
-
- return self;
- }
-
- - setStroking:sender
- {
- drawCombined = ([sender selectedRow] == 1);
-
- [NXApp redrawAction:self];
-
- return self;
- }
-
- - setParameterSetting:sender
- {
- drawEveryPath = ([sender selectedRow] == 1);
-
- [NXApp redrawAction:self];
-
- return self;
- }
-
- -setDrawOrigin:(NXPoint *)origin
- {
- drawOrigin = *origin;
-
- return self;
- }
-
- - freeGraphics
- {
- if (graphicsListId)
- [graphicsListId freeObjects];
-
- [graphicsListId free];
-
- return self;
- }
-
- - insertList:listId
- {
- [self freeGraphics];
- graphicsListId = listId;
-
- return self;
- }
-
- - eraseFields:sender
- {
- id matrixId;
-
- int i;
-
- matrixId = [NXApp getTimingMatrix];
- for (i= 0; i < [matrixId cellCount]; i++)
- [[matrixId cellAt:i :0] setStringValue:""];
-
- matrixId = [NXApp getStatusMatrix];
- for (i= 0; i < [matrixId cellCount]; i++)
- [[matrixId cellAt:i :0] setStringValue:""];
-
- return self;
- }
-
- - displayFields:sender
- {
- id matrixId;
-
- int i, ucache_values[5];
-
- if (timing_info.num_draws)
- {
- matrixId = [NXApp getTimingMatrix];
- [[matrixId cellAt:0 :0]
- setFloatValue:timing_info.num_draws];
- [[matrixId cellAt:1 :0]
- setFloatValue:timing_info.drawingtime/timing_info.num_draws];
- if (!drawFrame)
- {
- [[matrixId cellAt:2 :0]
- setFloatValue:timing_info.num_fills/timing_info.num_draws];
- [[matrixId cellAt:3 :0]
- setFloatValue:timing_info.num_strokes/timing_info.num_draws];
- }
- else
- [[matrixId cellAt:3 :0]
- setFloatValue:timing_info.num_strokes/timing_info.num_draws];
- [[matrixId cellAt:4 :0]
- setFloatValue:timing_info.num_subpaths/timing_info.num_draws];
- }
-
- if (drawManner == UCACHE)
- {
- matrixId = [NXApp getStatusMatrix];
- PSWUcachestatus(&ucache_values[0], &ucache_values[1],
- &ucache_values[2], &ucache_values[3], &ucache_values[4]);
- for (i= 0; i < [matrixId cellCount]; i++)
- [[matrixId cellAt:i :0] setIntValue:ucache_values[i]];
- }
-
- /* Prepare for next time around. */
- timing_info.num_fills = timing_info.num_strokes = 0;
- timing_info.num_subpaths = timing_info.num_draws = 0;
- timing_info.drawingtime = 0.0;
-
- return self;
- }
-
- /*
- * If the docview is zooming, then scale the drawing view.
- */
- - mouseDown:(NXEvent *)event
- {
- NXPoint p;
-
- p = event->location;
- if ([superview isZooming])
- {
- displayFields = eraseFields = YES;
- return [nextResponder scaleDrawView:self toPoint:&p];
- }
-
- return self;
- }
-
- /*
- * Initialize the user path structure. Always include a ucache.
- * If ucache is not used then start at the second entry in the op
- * array and decrement num_ops by one.
- */
- static void initUpath(UPath *aUpath)
- {
- aUpath->ops[0] = dps_ucache;
- aUpath->num_ops = 1;
-
- aUpath->pts[0] = 99999;
- aUpath->pts[1] = 99999;
- aUpath->pts[2] = -99999;
- aUpath->pts[3] = -99999;
- aUpath->num_pts = 4;
- }
-
- /*
- * Increment the stroke count and stroke the existing path.
- */
- static void strokeRedBook(int *strokes)
- {
- *strokes += 1;
- PSstroke();
- }
-
- /*
- * Call the appropriate wrap to construct the path. Not the recommended
- * approach to drawing (user paths are). Made external so Graphic.m
- * can make use of it.
- */
- void makeRedBook(UPath *aUpath)
- {
- int i_op, i_pt;
-
- i_pt = 4;
-
- /* Skip the ucache operator. */
- for (i_op = 1; i_op < aUpath->num_ops; i_op++)
- {
- switch (aUpath->ops[i_op])
- {
- case dps_moveto:
- PSmoveto(aUpath->pts[i_pt], aUpath->pts[i_pt+1]);
- i_pt += 2;
- break;
- case dps_rmoveto:
- PSrmoveto(aUpath->pts[i_pt], aUpath->pts[i_pt+1]);
- i_pt += 2;
- break;
- case dps_lineto:
- PSlineto(aUpath->pts[i_pt], aUpath->pts[i_pt+1]);
- i_pt += 2;
- break;
- case dps_rlineto:
- PSrlineto(aUpath->pts[i_pt], aUpath->pts[i_pt+1]);
- i_pt += 2;
- break;
- case dps_curveto:
- PScurveto(aUpath->pts[i_pt], aUpath->pts[i_pt+1],
- aUpath->pts[i_pt+2], aUpath->pts[i_pt+3],
- aUpath->pts[i_pt+4], aUpath->pts[i_pt+5]);
- i_pt += 6;
- break;
- case dps_rcurveto:
- PSrcurveto(aUpath->pts[i_pt], aUpath->pts[i_pt+1],
- aUpath->pts[i_pt+2], aUpath->pts[i_pt+3],
- aUpath->pts[i_pt+4], aUpath->pts[i_pt+5]);
- i_pt += 6;
- break;
- case dps_closepath:
- PSclosepath();
- break;
- }
- }
- }
-
- /*
- * If the ucache is to be used then include the first operator
- * otherwise skip it.
- */
- static void strokeUpath(UPath *aUpath, int manner, int *strokes)
- {
- *strokes += 1;
- if (manner == UCACHE)
- DPSDoUserPath(&aUpath->pts[4], aUpath->num_pts - 4, dps_float,
- &aUpath->ops[0], aUpath->num_ops, aUpath->pts, dps_ustroke);
- else
- DPSDoUserPath(&aUpath->pts[4], aUpath->num_pts - 4, dps_float,
- &aUpath->ops[1], aUpath->num_ops-1, aUpath->pts, dps_ustroke);
- }
-
- /*
- * Omit the bounding box numbers at the beginning of the operand
- * array as well as the dps_ucache at the beginning of the operator
- * array. Update the bounding box of the user path if necessary.
- */
- - getUpath:(NXRect *) r fromGraphic:graphicId
- {
- int ops_before;
-
- UPath *gUpath;
-
- [graphicId getUpath:&gUpath forRect:r];
- if (gUpath)
- {
- timing_info.num_subpaths++;
- if (!drawCombined)
- {
- if (drawManner == REDBOOK)
- {
- makeRedBook(gUpath);
- strokeRedBook(&timing_info.num_strokes);
- }
- else
- strokeUpath(gUpath, drawManner, &timing_info.num_strokes);
- }
- else
- {
- if (drawUpath->num_pts + gUpath->num_pts > PTS_UPATH_BUFFER ||
- drawUpath->num_ops + gUpath->num_ops > OPS_UPATH_BUFFER)
- {
- if (drawManner == REDBOOK)
- strokeRedBook(&timing_info.num_strokes);
- else
- strokeUpath(drawUpath, drawManner, &timing_info.num_strokes);
-
- initUpath(drawUpath);
- }
-
- if (drawManner == REDBOOK)
- makeRedBook(gUpath);
- else
- {
- bcopy(&gUpath->pts[4], &drawUpath->pts[drawUpath->num_pts],
- (gUpath->num_pts - 4)* (sizeof(float)/sizeof(char)));
- bcopy(&gUpath->ops[1], &drawUpath->ops[drawUpath->num_ops],
- gUpath->num_ops-1);
-
- drawUpath->pts[0] = MIN(gUpath->pts[0], drawUpath->pts[0]);
- drawUpath->pts[1] = MIN(gUpath->pts[1], drawUpath->pts[1]);
- drawUpath->pts[2] = MAX(gUpath->pts[2], drawUpath->pts[2]);
- drawUpath->pts[3] = MAX(gUpath->pts[3], drawUpath->pts[3]);
- }
-
- drawUpath->num_pts += gUpath->num_pts-4;
- drawUpath->num_ops += gUpath->num_ops-1;
- }
- }
-
- return self;
- }
-
- /*
- * Compare the bounds of the object with the rectangle to draw in order to
- * eliminate unnecessary drawing. The modal session stuff is just to
- * intercept the selection of the redraw button in the interface during
- * a trace. (This stops the drawing. It's only check during a trace
- * because the trace can be quite long.)
- */
- - drawSelf:(NXRect *)r :(int) count
- {
- int i, num, ElapsedTime;
-
- BOOL tracing;
-
- GParms parms;
- GParms *p_parms;
-
- NXRect rect;
- NXRect *p_rect;
-
- NXModalSession theSession;
-
- if (eraseFields)
- {
- [self eraseFields:self];
- eraseFields = NO;
- }
-
- PSsetgray(NX_WHITE);
- NXRectFill(r);
-
- initGparms(&parms);
- if (drawFrame)
- {
- parms.linewidth = 0.05;
- initUpath(drawUpath);
- }
- else
- {
- if (drawEveryPath)
- p_parms = NULL;
- else
- p_parms = &parms;
- }
- setGparms(&parms);
- NXSetColor(parms.color);
-
- if (drawEverything)
- p_rect = NULL;
- else
- {
- rect = *r;
- rect.origin.x += drawOrigin.x;
- rect.origin.y += drawOrigin.y;
- p_rect = ▭
- }
-
- tracing = [NXApp tracing];
- if (tracing)
- {
- [[NXApp redrawButton] setTitle:"STOP"];
-
- [NXApp beginModalSession:&theSession for:[NXApp methodsWindow]];
- DPSTraceContext(DPSGetCurrentContext(), YES);
- }
-
- PSgsave();
- NXRectClip(r);
- PStranslate(-drawOrigin.x, -drawOrigin.y);
- PSWMarkTime (); NXPing();
- num = [graphicsListId count];
- for (i = 0; i < num; i++)
- {
- if (tracing && (i % MODALTRACE == 0))
- if ([NXApp runDrawModalSession:&theSession] != NX_RUNCONTINUES)
- break;
-
- if (drawFrame)
- [self getUpath:p_rect fromGraphic:[graphicsListId objectAt:i]];
- else
- [[graphicsListId objectAt:i] drawObject:p_rect currentParms:p_parms
- withManner:drawManner timingInfo:&timing_info];
- }
-
- if (drawFrame && drawCombined)
- {
- if (drawManner == REDBOOK)
- strokeRedBook(&timing_info.num_strokes);
- else
- strokeUpath(drawUpath, drawManner, &timing_info.num_strokes);
- }
-
- PSWReturnTime (&ElapsedTime);
- PSgrestore();
-
- if (tracing)
- {
- DPSTraceContext(DPSGetCurrentContext(), NO);
- [NXApp endModalSession:&theSession];
-
- [[NXApp redrawButton] setTitle:"redraw"];
- }
-
- timing_info.drawingtime += ElapsedTime;
- ++timing_info.num_draws;
-
- if (displayFields)
- {
- [self displayFields:self];
- displayFields = NO;
- eraseFields = YES;
- }
-
- return self;
- }
-
- @end
-